package com.yzxb.messystem.util;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
import java.util.Date;
import java.util.TimeZone;

public class DateUtils {
    
    // 常用日期格式化模式
    public static final String PATTERN_ISO = "yyyy-MM-dd'T'HH:mm:ss";
    public static final String PATTERN_DATE = "yyyy-MM-dd";
    public static final String PATTERN_TIME = "HH:mm:ss";
    public static final String PATTERN_DATETIME = "yyyy-MM-dd HH:mm:ss";
    public static final String PATTERN_YEAR_MONTH = "yyyyMM";
    public static final String PATTERN_YEAR_MONTH_DAY = "yyyyMMdd";
    public static final String PATTERN_YEAR_MONTH_DAY_HOUR_MINUTE = "yyyyMMddHHmm";
    public static final String PATTERN_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND = "yyyyMMddHHmmss";
    
    // 默认时区
    public static final String DEFAULT_TIMEZONE = "Asia/Shanghai";
    
    // 获取当前日期时间（本地时间）
    public static LocalDateTime now() {
        return LocalDateTime.now();
    }
    
    // 获取当前日期
    public static LocalDate today() {
        return LocalDate.now();
    }
    
    // 获取当前时间
    public static LocalTime currentTime() {
        return LocalTime.now();
    }
    
    // 格式化LocalDateTime为字符串
    public static String format(LocalDateTime dateTime, String pattern) {
        if (dateTime == null || pattern == null) {
            return null;
        }
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
        return dateTime.format(formatter);
    }
    
    // 格式化LocalDate为字符串
    public static String format(LocalDate date, String pattern) {
        if (date == null || pattern == null) {
            return null;
        }
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
        return date.format(formatter);
    }
    
    // 解析字符串为LocalDateTime
    public static LocalDateTime parseDateTime(String dateTimeStr, String pattern) {
        if (dateTimeStr == null || pattern == null) {
            return null;
        }
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
        return LocalDateTime.parse(dateTimeStr, formatter);
    }
    
    // 解析字符串为LocalDate
    public static LocalDate parseDate(String dateStr, String pattern) {
        if (dateStr == null || pattern == null) {
            return null;
        }
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
        return LocalDate.parse(dateStr, formatter);
    }
    
    // 将Date转换为LocalDateTime
    public static LocalDateTime dateToLocalDateTime(Date date) {
        if (date == null) {
            return null;
        }
        return date.toInstant()
                .atZone(ZoneId.of(DEFAULT_TIMEZONE))
                .toLocalDateTime();
    }
    
    // 将LocalDateTime转换为Date
    public static Date localDateTimeToDate(LocalDateTime dateTime) {
        if (dateTime == null) {
            return null;
        }
        return Date.from(dateTime
                .atZone(ZoneId.of(DEFAULT_TIMEZONE))
                .toInstant());
    }
    
    // 获取指定日期的开始时间（00:00:00）
    public static LocalDateTime startOfDay(LocalDateTime dateTime) {
        if (dateTime == null) {
            return null;
        }
        return dateTime.withHour(0).withMinute(0).withSecond(0).withNano(0);
    }
    
    // 获取指定日期的结束时间（23:59:59.999999999）
    public static LocalDateTime endOfDay(LocalDateTime dateTime) {
        if (dateTime == null) {
            return null;
        }
        return dateTime.withHour(23).withMinute(59).withSecond(59).withNano(999999999);
    }
    
    // 获取本月第一天
    public static LocalDate firstDayOfMonth() {
        return today().with(TemporalAdjusters.firstDayOfMonth());
    }
    
    // 获取本月最后一天
    public static LocalDate lastDayOfMonth() {
        return today().with(TemporalAdjusters.lastDayOfMonth());
    }
    
    // 获取本周第一天（周一）
    public static LocalDate firstDayOfWeek() {
        return today().with(DayOfWeek.MONDAY);
    }
    
    // 获取本周最后一天（周日）
    public static LocalDate lastDayOfWeek() {
        return today().with(DayOfWeek.SUNDAY);
    }
    
    // 计算两个日期之间的天数差
    public static long daysBetween(LocalDate startDate, LocalDate endDate) {
        if (startDate == null || endDate == null) {
            return 0;
        }
        return ChronoUnit.DAYS.between(startDate, endDate);
    }
    
    // 计算两个日期时间之间的小时差
    public static long hoursBetween(LocalDateTime startDateTime, LocalDateTime endDateTime) {
        if (startDateTime == null || endDateTime == null) {
            return 0;
        }
        return ChronoUnit.HOURS.between(startDateTime, endDateTime);
    }
    
    // 计算两个日期时间之间的分钟差
    public static long minutesBetween(LocalDateTime startDateTime, LocalDateTime endDateTime) {
        if (startDateTime == null || endDateTime == null) {
            return 0;
        }
        return ChronoUnit.MINUTES.between(startDateTime, endDateTime);
    }
    
    // 添加天数
    public static LocalDateTime plusDays(LocalDateTime dateTime, long days) {
        if (dateTime == null) {
            return null;
        }
        return dateTime.plusDays(days);
    }
    
    // 添加月数
    public static LocalDateTime plusMonths(LocalDateTime dateTime, long months) {
        if (dateTime == null) {
            return null;
        }
        return dateTime.plusMonths(months);
    }
    
    // 添加年数
    public static LocalDateTime plusYears(LocalDateTime dateTime, long years) {
        if (dateTime == null) {
            return null;
        }
        return dateTime.plusYears(years);
    }
    
    // 减少天数
    public static LocalDateTime minusDays(LocalDateTime dateTime, long days) {
        if (dateTime == null) {
            return null;
        }
        return dateTime.minusDays(days);
    }
    
    // 判断日期是否在指定范围内
    public static boolean isBetween(LocalDate date, LocalDate startDate, LocalDate endDate) {
        if (date == null || startDate == null || endDate == null) {
            return false;
        }
        return !date.isBefore(startDate) && !date.isAfter(endDate);
    }
    
    // 判断日期时间是否在指定范围内
    public static boolean isBetween(LocalDateTime dateTime, LocalDateTime startDateTime, LocalDateTime endDateTime) {
        if (dateTime == null || startDateTime == null || endDateTime == null) {
            return false;
        }
        return !dateTime.isBefore(startDateTime) && !dateTime.isAfter(endDateTime);
    }
}